//----------------------------------
// Create a namespace Gadget 
//----------------------------------                     
if ("undefined" == typeof (Gadget)) {
    Gadget = new Object();
}

//---------------------------------------------------------------------------------
// JavaScript library to load any .NET assembly/type and execute against its 
// public methods and properties
//---------------------------------------------------------------------------------
if ("undefined" == typeof (Gadget.Interop)) {
    Gadget.Interop = new Object();

    //Service Object
    Gadget.Interop.Service = null;
}

//-----------------------------------------------------------------------------------
// Inits this class by creating an instance of the Gadget Interop Service.  
// If the Gadget Service assembly is not yet retistered, the corresponding registry
// values are added to register the Gadget Service.  (i.e. runtime registration)
//-----------------------------------------------------------------------------------
Gadget.Interop.Service = function() {
    var _progID = "Gadget.Interop.Service";
    var _assemblyName = "Gadget.Interop.dll";
    var _classID = "{8D64724D-B977-4b01-B9FE-B446C90D6CB3}";
    var _assemblyPath = "\\bin\\";

    //---------------------------------------------------------------------------------
    // Add the Gadget.Interop dll to the registry so it can be used by COM and
    // created in javascript as an ActiveX object
    //---------------------------------------------------------------------------------
    function RegisterGadgetInterop() {
        try {
            // Full path to the Gadget.Interop.dll assembly
            var fullPath = System.Gadget.path + _assemblyPath;
            var asmPath = fullPath + _assemblyName;

            // Register the interop assembly under the Current User registry key
            RegAsmInstall("HKCU", _progID, "Gadget.Interop.Service", _classID,
            "Gadget.Interop, Version=1.0.0.0, Culture=neutral, PublicKeyToken=2cf0ff80e7ffb492",
            "1.0.0.0", asmPath);
        }
        catch (e)
    { }
    }

    //---------------------------------------------------------------------------------
    // Remove the Gadget.Interop dll from the registry and the GAC
    //---------------------------------------------------------------------------------
    function UnregisterGadgetInterop() {
        try {
            var fullPath = System.Gadget.path + _assemblyPath;
            var asmPath = fullPath + _assemblyName;

            RegAsmUninstall("HKLM", _progID, "Gadget.Interop.Service", _classID,
            "Gadget.Interop, Version=1.0.0.0, Culture=neutral, PublicKeyToken=2cf0ff80e7ffb492",
            "1.0.0.0", asmPath);
        }
        catch (e)
    { }
    }

    //---------------------------------------------------------------------------------
    // Returns true if a Gadget Service ActiveX object is successfully created,
    // otherwise returns false.
    //---------------------------------------------------------------------------------
    function IsRegistred() {
        try {
            var proxy = this.GetService();
            proxy = null;

            return true;
        }
        catch (e) {
            return false;
        }
    }

    //---------------------------------------------------------------------------------
    // Attempts to create and return an instance of the Gadget Service ActiveX object.
    //---------------------------------------------------------------------------------
    function GetService() {
        return new ActiveXObject(_progID);
    }

    //---------------------------------------------------------------------------------
    // Code to register a .NET type for COM interop
    //---------------------------------------------------------------------------------
    function RegAsmInstall(root, progID, cls, clsid, assembly, version, codebase) {
        var wshShell;
        wshShell = new ActiveXObject("WScript.Shell");

        wshShell.RegWrite(root + "\\Software\\Classes\\", progID);
        wshShell.RegWrite(root + "\\Software\\Classes\\" + progID + "\\", cls);
        wshShell.RegWrite(root + "\\Software\\Classes\\" + progID + "\\CLSID\\", clsid);
        wshShell.RegWrite(root + "\\Software\\Classes\\CLSID\\" + clsid + "\\", cls);

        wshShell.RegWrite(root + "\\Software\\Classes\\CLSID\\" + clsid + "\\InprocServer32\\", "mscoree.dll");
        wshShell.RegWrite(root + "\\Software\\Classes\\CLSID\\" + clsid + "\\InprocServer32\\ThreadingModel", "Both");
        wshShell.RegWrite(root + "\\Software\\Classes\\CLSID\\" + clsid + "\\InprocServer32\\Class", cls);
        wshShell.RegWrite(root + "\\Software\\Classes\\CLSID\\" + clsid + "\\InprocServer32\\Assembly", assembly);
        wshShell.RegWrite(root + "\\Software\\Classes\\CLSID\\" + clsid + "\\InprocServer32\\RuntimeVersion", "v2.0.50727");
        wshShell.RegWrite(root + "\\Software\\Classes\\CLSID\\" + clsid + "\\InprocServer32\\CodeBase", codebase);

        wshShell.RegWrite(root + "\\Software\\Classes\\CLSID\\" + clsid + "\\InprocServer32\\" + version + "\\Class", cls);
        wshShell.RegWrite(root + "\\Software\\Classes\\CLSID\\" + clsid + "\\InprocServer32\\" + version + "\\Assembly", assembly);
        wshShell.RegWrite(root + "\\Software\\Classes\\CLSID\\" + clsid + "\\InprocServer32\\" + version + "\\RuntimeVersion", "v2.0.50727");
        wshShell.RegWrite(root + "\\Software\\Classes\\CLSID\\" + clsid + "\\InprocServer32\\" + version + "\\CodeBase", codebase);

        wshShell.RegWrite(root + "\\Software\\Classes\\CLSID\\" + clsid + "\\_progID\\", progID);

        wshShell.RegWrite(root + "\\Software\\Classes\\CLSID\\" + clsid + "\\Implemented Categories\\{62C8FE65-4EBB-45E7-B440-6E39B2CDBF29}\\", "");
    }

    //---------------------------------------------------------------------------------
    // Code to unregister a .NET type for COM interop
    //---------------------------------------------------------------------------------
    function RegAsmUninstall(root, progID, clsid) {
        var wshShell;
        wshShell = new ActiveXObject("WScript.Shell");

        wshShell.RegDelete(root + "\\Software\\Classes\\", progID);
        wshShell.RegDelete(root + "\\Software\\Classes\\CLSID\\" + clsid);
    }

    if (IsRegistred() == false) {
        RegisterGadgetInterop();
    }

    this.Service = GetService();
}

//---------------------------------------------------------------------------------
// Load the specified .NET type from the given assembly
//---------------------------------------------------------------------------------
Gadget.Interop.LoadType = function(assemblyPath, classType) {
    try {
        return this.Service.LoadType(assemblyPath, classType);
    }
    catch (e) {
        return null;
    }
}

//--------------------------------------------------------------------------------------
// Load the specified type from the given assembly.  The "preserve" argument provides 
// control over clearing the constructor arguments after object creating
//--------------------------------------------------------------------------------------
Gadget.Interop.LoadTypeWithParams = function(assemblyPath, classType, preserve) {
    try {
        return this.Service.LoadTypeWithParams(assemblyPath, classType, preserve);
    }
    catch (e) {
        return null;
    }
}

//---------------------------------------------------------------------------------
// Call the object's Dispose method
//---------------------------------------------------------------------------------
Gadget.Interop.UnloadType = function(typeToUnload) {
    try {
        this.Service.UnloadType(typeToUnload);
    }
    catch (e)
    { }
}

//---------------------------------------------------------------------------------
// Add a parameter to the list of objects needed to call the class' constructor
//---------------------------------------------------------------------------------
Gadget.Interop.AddConstructorParam = function(param) {
    this.Service.AddConstructorParam(param);
}